package com.tengju.user.application.user;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tengju.data.domain.model.alert.AlertEvent;
import com.tengju.data.domain.model.alert.AlertService;
import com.tengju.data.domain.model.clickhouse.DwdStarChangeRecordAllRepository;
import com.tengju.data.domain.model.clickhouse.DwdUserClubMapRepository;
import com.tengju.data.domain.model.clickhouse.DwdUserRelationMapAllRepository;
import com.tengju.data.domain.model.clickhouse.star.DwdStarChangeRecord;
import com.tengju.data.domain.model.clickhouse.star.StarChangeNoticeRecord;
import com.tengju.data.domain.model.clickhouse.star.StarChangeNoticeRecordRepository;
import com.tengju.data.domain.model.clickhouse.star.StarChangeNoticeType;
import com.tengju.data.domain.model.user.StarLevelEnum;
import com.tengju.data.domain.model.user.UserLevelEnum;
import com.tengju.data.domain.model.user.*;
import com.tengju.user.application.user.dto.UserSearchForm;
import com.tengju.user.domain.model.club.Club;
import com.tengju.user.domain.model.club.ClubId;
import com.tengju.user.domain.model.club.ClubRepository;
import com.tengju.user.domain.model.doc.DominationNoteDocument;
import com.tengju.user.domain.model.doc.SentimentDocument;
import com.tengju.user.domain.model.doc.UserDocument;
import com.tengju.user.domain.model.sentiment.Sentiment;
import com.tengju.user.domain.model.sentiment.SentimentRepository;
import com.tengju.user.domain.model.sign.*;
import com.tengju.user.domain.model.user.UserId;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.*;
import com.tengju.user.domain.service.RemoteUserService;
import com.tengju.user.domain.service.UserDocumentTemplate;
import com.tengju.user.domain.shared.DateUtil;
import com.tengju.user.domain.shared.ElasticsearchIndexNameEnum;
import com.tengju.user.domain.shared.IdObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.temporal.ChronoField;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: 李大仙
 * @Date: 2021/3/24 3:24 下午
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class UserDocumentJobService {

    private final UserDocumentService userDocumentService;
    private final UserDocumentTemplate userDocumentTemplate;
    private final DealerInfoRepository dealerInfoRepository;
    private final DwdUserClubMapRepository dwdUserClubMapRepository;
    private final ClubRepository clubRepository;
    private final UserInfoRepository userInfoRepository;
    private final StarSignInfoRepository starSignInfoRepository;
    private final StarChangeRecordRepository starChangeRecordRepository;
    private final DwdUserRelationMapAllRepository dwdUserRelationMapAllRepository;
    private final StarChangeNoticeRecordRepository starChangeNoticeRecordRepository;
    private final SentimentRepository sentimentRepository;
    private final DominationMemberNoteRepository dominationMemberNoteRepository;
    private final DealerBrandProviderRepository dealerBrandProviderRepository;
    private final RemoteUserService remoteUserService;
    private final AlertService alertService;

    @Value("${sync.es.alert.lark.url}")
    private String syncEsAlertLarkUrl;

    final ExecutorService singleThread = new ThreadPoolExecutor(1, 1,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>());
    private final DwdStarChangeRecordAllRepository dwdStarChangeRecordAllRepository;

    public void execute() {
        int limit = 500;
        int offset = 0;
        long startTime = System.currentTimeMillis();
        while (true) {
            try {
                List<Long> idCodeList = dwdUserRelationMapAllRepository.getIdCodeAndStarLevel(offset, limit);
                if (CollectionUtils.isEmpty(idCodeList)) {
                    int finalOffset = offset;
                    singleThread.execute(() -> {
                        AlertEvent alertEvent = new AlertEvent("es同步数据完成：");
                        alertEvent.addItem("总条数", finalOffset);
                        alertEvent.addItem("耗时", System.currentTimeMillis() - startTime);
                        for (StarLevelEnum starLevelEnum : StarLevelEnum.values()) {
                            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
                            queryBuilder.must(QueryBuilders.termQuery(UserDocument.STAR_LEVEL, starLevelEnum.getCode()));
                            queryBuilder.must(QueryBuilders.termQuery(UserDocument.BRAND_PROVIDER_LEVEL, UserLevelEnum.BLACK.getCode()));
                            long cityStarOneCount = userDocumentTemplate.count(ElasticsearchIndexNameEnum.USER_DOCUMENT, queryBuilder);
                            alertEvent.addItem(starLevelEnum.getDesc(), cityStarOneCount);
                        }
                        alertService.alert(alertEvent, syncEsAlertLarkUrl);
                    });
                    return;
                }
                offset = offset + idCodeList.size();
                getInfoAndSaveDocument(idCodeList);
            } catch (Exception e) {
                log.error("job execute error", e);
            }
        }
    }

    public void getInfoAndSaveDocument(List<Long> idCodeList) {
        List<UserIdCode> userIdCodeList = idCodeList.stream().map(UserIdCode::new).collect(Collectors.toList());
        // w_user 经销商信息
        List<UserInfo> remoteDealerInfos = remoteUserService.getByIdList(userIdCodeList);
        Map<Long, UserInfo> idCodeRemoteDealerInfoMap = remoteDealerInfos.stream()
                .collect(Collectors.toMap(d -> d.getIdCode().getValue(), d -> d, (v1, v2) -> v1));

        userIdCodeList = remoteDealerInfos.stream()
                .map(UserInfo::getIdCode)
                .collect(Collectors.toList());

        // 查询本地w_user，获取createAt
        List<com.tengju.data.domain.model.user.UserId> userIds = remoteDealerInfos.stream()
                .map(UserInfo::getUserId)
                .map(IdObject::getValue)
                .map(com.tengju.data.domain.model.user.UserId::new)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(userIdCodeList) || CollectionUtils.isEmpty(userIds)) {
            return;
        }

        List<DealerInfo> dealerInfos = dealerInfoRepository.getByIds(userIds);
        Map<Long, DealerInfo> idCodeDealerInfoMap = dealerInfos.stream()
                .filter(d -> d.getIdCode() != null)
                .collect(Collectors.toMap(d -> d.getIdCode().getValue(), d -> d, (v1, v2) -> v1));

        // 俱乐部、ec、sec、eec、genSec
        List<UserBelongDetail> userBelongDetails = dwdUserClubMapRepository.queryUserBelongDetailList(userIdCodeList);
        Map<Long, UserBelongDetail> idCodeUserBelongDetailMap = userBelongDetails.stream()
                .collect(Collectors.toMap(d -> d.getIdCode().getValue(), d -> d));

        // 俱乐部信息
        List<ClubId> clubIdList = userBelongDetails.stream().map(UserBelongDetail::getBelongClubId)
                .filter(clubId -> clubId != null && clubId.getValue() > 0)
                .collect(Collectors.toList());
        List<Club> clubList = clubRepository.findByIds(clubIdList);
        Map<Long, Club> clubIdClubMap = clubList.stream()
                .collect(Collectors.toMap(c -> c.getClubId().getValue(), c -> c));

        // user_info 服务商信息
        List<UserInfo> userInfoList = userInfoRepository.batchGetUserInfo(userIdCodeList);
        Map<Long, UserInfo> idCodeUserInfoMap = userInfoList.stream()
                .collect(Collectors.toMap(u -> u.getIdCode().getValue(), c -> c));

        // 客情信息
        List<Sentiment> sentimentList = sentimentRepository.getByIdCodes(userIdCodeList);
        Map<Long, List<Sentiment>> idCodeSentimentListMap = Maps.newHashMap();
        for (Sentiment sentiment : sentimentList) {
            if (idCodeSentimentListMap.containsKey(sentiment.getIdCode().getValue())) {
                List<Sentiment> sentiments = idCodeSentimentListMap.get(sentiment.getIdCode().getValue());
                sentiments.add(sentiment);
            } else {
                List<Sentiment> sentiments = Lists.newArrayList();
                sentiments.add(sentiment);
                idCodeSentimentListMap.put(sentiment.getIdCode().getValue(), sentiments);
            }
        }

        // 签约信息
        List<StarSignInfo> signStatusList = starSignInfoRepository.getSignStatusByIdCode(userIdCodeList);
        Map<Long, StarSignInfo> idCodeStarSignInfoMap = signStatusList.stream()
                .collect(Collectors.toMap(u -> u.getIdCode().getValue(), c -> c));

        // 签约变更记录
        List<StarChangeRecord> starChangeRecords = starChangeRecordRepository.batchGetLastChangeRecord(userIdCodeList);
        Map<Long, StarChangeRecord> idCodeStarChangeRecordMap = starChangeRecords.stream()
                .collect(Collectors.toMap(u -> u.getIdCode().getValue(), c -> c));

        //即将晋升名单
        List<com.tengju.data.domain.model.user.UserIdCode> dataUserIdCodeList = userIdCodeList.stream()
                .map(com.tengju.user.domain.model.user.UserIdCode::getValue)
                .map(com.tengju.data.domain.model.user.UserIdCode::new)
                .collect(Collectors.toList());
        List<StarChangeNoticeRecord> starChangeNoticeRecordList = starChangeNoticeRecordRepository.listStarChangeNoticeRecord(StarChangeNoticeType.UP_SOON, dataUserIdCodeList);
        Map<Long, StarChangeNoticeRecord> idCodeStarChangeNoticeRecordMap = starChangeNoticeRecordList.stream()
                .collect(Collectors.toMap(u -> u.getIdCode().getValue(), c -> c));

        //备注
        Map<UserIdCode, List<DominationMemberNote>> noteMap =
                dominationMemberNoteRepository.getBySubordinateIds(userIdCodeList);

        List<DwdStarChangeRecord> lastRecords = dwdStarChangeRecordAllRepository.getLastRecord(dataUserIdCodeList);

        Map<UserIdCode, DwdStarChangeRecord> lastRecordMap =
                lastRecords.stream().collect(Collectors.toMap(v -> new UserIdCode(v.getIdCode().getValue()), Function.identity()));


        saveDocument(userIdCodeList, idCodeRemoteDealerInfoMap, idCodeDealerInfoMap, idCodeUserBelongDetailMap, clubIdClubMap,
                idCodeUserInfoMap, idCodeSentimentListMap, idCodeStarSignInfoMap, idCodeStarChangeRecordMap, idCodeStarChangeNoticeRecordMap, noteMap, lastRecordMap);
    }


    private void saveDocument(List<UserIdCode> userIdCodeList,
                              Map<Long, UserInfo> idCodeRemoteDealerInfoMap,
                              Map<Long, DealerInfo> idCodeDealerInfoMap,
                              Map<Long, UserBelongDetail> idCodeUserBelongDetailMap,
                              Map<Long, Club> clubIdClubMap,
                              Map<Long, UserInfo> idCodeUserInfoMap,
                              Map<Long, List<Sentiment>> idCodeSentimentListMap,
                              Map<Long, StarSignInfo> idCodeStarSignInfoMap,
                              Map<Long, StarChangeRecord> idCodeStarChangeRecordMap,
                              Map<Long, StarChangeNoticeRecord> idCodeStarChangeNoticeRecordMap,
                              Map<UserIdCode, List<DominationMemberNote>> noteMap,
                              Map<UserIdCode, DwdStarChangeRecord> lastRecordMap) {
        List<UserDocument> documents = Lists.newArrayList();
        for (UserIdCode userIdCode : userIdCodeList) {
            Long idCode = userIdCode.getValue();
            Long abmUserId = Optional.ofNullable(idCodeRemoteDealerInfoMap.get(idCode))
                    .map(UserInfo::getUserId)
                    .map(UserId::getValue)
                    .orElse(0L);

            String abmHeadImage = Optional.ofNullable(idCodeRemoteDealerInfoMap.get(idCode))
                    .map(UserInfo::getHeadImage)
                    .orElse("");
            String mobile = Optional.ofNullable(idCodeRemoteDealerInfoMap.get(idCode))
                    .map(UserInfo::getWholePhoneNumber).orElse("");
            Long parentIdCode = Optional.ofNullable(idCodeRemoteDealerInfoMap.get(idCode))
                    .map(UserInfo::getPidCode)
                    .map(UserIdCode::getValue)
                    .orElse(0L);
            String abmNickName = Optional.ofNullable(idCodeRemoteDealerInfoMap.get(idCode))
                    .map(UserInfo::getNickName).orElse("");
            Long registerTime = Optional.ofNullable(idCodeDealerInfoMap.get(idCode))
                    .map(DealerInfo::getCreateTime).map(Date::getTime).orElse(0L);
            String abmName = Optional.ofNullable(idCodeRemoteDealerInfoMap.get(idCode))
                    .map(UserInfo::getName).orElse("");
            Integer brandProviderLevel = Optional.ofNullable(idCodeRemoteDealerInfoMap.get(idCode))
                    .map(UserInfo::getAbmLevel)
                    .orElse(0);

            Long clubId = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getBelongClubId).map(IdObject::getValue)
                    .orElse(0L);
            String clubName = Optional.ofNullable(clubIdClubMap.get(clubId))
                    .map(Club::getClubName).orElse("");

            Long blackAddDate = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getUpgradeBlackCardTime)
                    .map(DateUtil::toLong)
                    .orElse(null);

            Long cityIdCode = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getCityIdCode).map(UserIdCode::getValue)
                    .orElse(0L);
            Long ecIdCode = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getBelongEc).map(UserIdCode::getValue)
                    .orElse(0L);
            Long secIdCode = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getBelongSec).map(UserIdCode::getValue)
                    .orElse(0L);
            Long eecIdCode = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getBelongEec).map(UserIdCode::getValue)
                    .orElse(0L);
            Long genSecIdCode = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getGenSecIdCode).map(UserIdCode::getValue)
                    .orElse(0L);
            Long genOperatorIdCode = Optional.ofNullable(idCodeUserBelongDetailMap.get(idCode))
                    .map(UserBelongDetail::getGenOperatorIdCode).map(UserIdCode::getValue)
                    .orElse(0L);

            Long tjUserId = Optional.ofNullable(idCodeUserInfoMap.get(idCode))
                    .map(UserInfo::getId).orElse(0L);
            String tjNickName = Optional.ofNullable(idCodeUserInfoMap.get(idCode))
                    .map(UserInfo::getNickName).orElse("");
            Integer starLevel = Optional.ofNullable(idCodeUserInfoMap.get(idCode))
                    .map(UserInfo::getStarLevel).orElse(0);
            String tjName = Optional.ofNullable(idCodeUserInfoMap.get(idCode))
                    .map(UserInfo::getName).orElse("");
            if (StarLevelEnum.NONE.getCode().equals(starLevel)) {
                tjNickName = abmNickName;
            }
            String name = StringUtils.isEmpty(tjName) ? abmName : tjName;

            String tjHeadImage = Optional.ofNullable(idCodeUserInfoMap.get(idCode))
                    .map(UserInfo::getHeadImage).orElse("");

            Integer step = Optional.ofNullable(idCodeStarSignInfoMap.get(idCode))
                    .map(StarSignInfo::getStep).orElse(0);
            Integer auditStat = Optional.ofNullable(idCodeStarSignInfoMap.get(idCode))
                    .map(StarSignInfo::getAuditStat).orElse(0);
            Integer starSignStatus = Optional.ofNullable(StarSignStatus.fromStepAndAuditStat(StarSignStepEnum.getByStep(step),
                    StarAuditStatEnum.fromVal(auditStat)))
                    .map(StarSignStatus::getVal).orElse(0);
            Integer signTargetStarLevel = Optional.ofNullable(idCodeStarSignInfoMap.get(idCode))
                    .map(StarSignInfo::getStarLevel).orElse(0);

            StarChangeRecord starChangeRecord = idCodeStarChangeRecordMap.get(idCode);
            Long starRiseTime = Optional.ofNullable(starChangeRecord)
                    .map(StarChangeRecord::getChangeTime)
                    .map(DateUtil::toLong)
                    .orElse(null);

            Long starAddDate = 0L;
            if (starChangeRecord != null) {
                if (starChangeRecord.getAfterStarLevel() > starChangeRecord.getBeforeStarLevel()) {
                    starAddDate = DateUtil.toLong(starChangeRecord.getChangeTime());
                }
            }

            Integer targetStarLevel = Optional.ofNullable(idCodeStarChangeNoticeRecordMap.get(idCode))
                    .map(v -> v.getTargetStarLevel().getCode()).orElse(0);

            List<DominationMemberNote> dominationMemberNoteList = noteMap.get(new UserIdCode(idCode));

            List<DominationNoteDocument> dominationNoteDocuments = Lists.newArrayList();
            if (!CollectionUtils.isEmpty(dominationMemberNoteList)) {
                dominationNoteDocuments = dominationMemberNoteList.stream()
                        .map(dominationMemberNote -> new DominationNoteDocument(dominationMemberNote.getLeaderId().getValue(),
                                dominationMemberNote.getRemark()))
                        .collect(Collectors.toList());
            }

            DwdStarChangeRecord dwdStarChangeRecord = lastRecordMap.get(new UserIdCode(idCode));
            long lastDemotionTime = 0L;
            int lastDemotionOperating = 0;
            if (dwdStarChangeRecord != null) {
                lastDemotionOperating = dwdStarChangeRecord.getAfterStarLevel() > dwdStarChangeRecord.getBeforeStarLevel() ? 1 : 2;
                lastDemotionTime = Optional.of(dwdStarChangeRecord)
                        .map(DwdStarChangeRecord::getUpgradingTime).map(DateUtil::localDateTimeToDate).map(Date::getTime).orElse(0L);
            }

            //客情记录
            List<SentimentDocument> sentimentDocs = new ArrayList<>();
            List<Sentiment> sentiments = idCodeSentimentListMap.get(idCode);
            if (!CollectionUtils.isEmpty(sentiments)) {
                for (Sentiment sentiment : sentiments) {
                    SentimentDocument sentimentDoc = new SentimentDocument();
                    sentimentDoc.setContext(sentiment.getContent());
                    sentimentDoc.setOperator(sentiment.getOperator());
                    sentimentDoc.setCreateTime(DateUtil.toLong(sentiment.getCreateTime()));
                    sentimentDocs.add(sentimentDoc);
                }
            }


            UserDocument document = UserDocument.builder()
                    .idCode(idCode)
                    .tjUserId(tjUserId)
                    .abmUserId(abmUserId)
                    .mobile(mobile)
                    .parentIdCode(parentIdCode)
                    .starLevel(starLevel)
                    .brandProviderLevel(brandProviderLevel)
                    .starSignStatus(starSignStatus)
                    .signTargetStarLevel(signTargetStarLevel)
                    .targetStarLevel(targetStarLevel)
                    .starAddDate(starAddDate)
                    .blackAddDate(blackAddDate)
                    .clubId(clubId)
                    .clubName(clubName)
                    .nickName(tjNickName)
                    .registerTime(registerTime)
                    .starRiseTime(starRiseTime)
                    .ownerEcIdCode(ecIdCode)
                    .ownerSecIdCode(secIdCode)
                    .ownerEecIdCode(eecIdCode)
                    .ownerGenSecIdCode(genSecIdCode)
                    .ownerCityIdCode(cityIdCode)
                    .name(name)
                    .ownerGenOperatorIdCode(genOperatorIdCode)
                    .abmHeadImage(abmHeadImage)
                    .tengjuHeadImage(tjHeadImage)
                    .dominationNotes(dominationNoteDocuments)
                    .lastDemotionOperating(lastDemotionOperating)
                    .lastDemotionTime(lastDemotionTime)
                    .sentiments(sentimentDocs)
                    .build();
            documents.add(document);
        }
        if (!CollectionUtils.isEmpty(documents)) {
            userDocumentService.saveAll(documents);
        }
    }

    public void saveMotivationStarChangeRecord(String primaryKey) {
        StarChangeRecord starChangeRecord = starChangeRecordRepository.getById(new StarChangeRecordId(Long.parseLong(primaryKey)));
        if (starChangeRecord != null) {
            getInfoAndSaveDocument(Lists.newArrayList(starChangeRecord.getIdCode().getValue()));
        }
    }

    public void saveMotivationStarSignInfo(String primaryKey) {
        StarSignInfo starSignInfo = starSignInfoRepository.getById(new SignId(Long.parseLong(primaryKey)));
        if (starSignInfo != null) {
            getInfoAndSaveDocument(Lists.newArrayList(starSignInfo.getIdCode().getValue()));
        }
    }

    public void saveDominationMemberNote(String primaryKey) {
        DominationMemberNote dominationMemberNote = dominationMemberNoteRepository.getById(Long.parseLong(primaryKey));
        if (dominationMemberNote != null) {
            getInfoAndSaveDocument(Lists.newArrayList(dominationMemberNote.getSubordinateId().getValue()));
        }
    }


    public void saveUserInfo(String primaryKey) {
        UserInfo userInfo = userInfoRepository.getByUserId(new UserId(Long.parseLong(primaryKey)));
        if (userInfo != null) {
            if (userInfo.getIdCode() != null) {
                getInfoAndSaveDocument(Lists.newArrayList(userInfo.getIdCode().getValue()));
            }
        } else {
            // 删除
            UserSearchForm form = new UserSearchForm();
            form.setTjUserId(new UserId(Long.parseLong(primaryKey)));
            Page<UserDocument> documentList = userDocumentService.search(form);
            if (!documentList.isEmpty()) {
                for (UserDocument document : documentList) {
                    userDocumentService.deleteByIdCode(new UserIdCode(document.getIdCode()));
                }
            }
        }
    }

    public void saveUser(String primaryKey) {
        DealerInfo dealerInfo = dealerInfoRepository.getById(new com.tengju.data.domain.model.user.UserId(Long.parseLong(primaryKey)));
        if (dealerInfo != null) {
            if (dealerInfo.getIdCode() != null) {
                getInfoAndSaveDocument(Lists.newArrayList(dealerInfo.getIdCode().getValue()));
            }
        } else {
            // 删除
            UserSearchForm form = new UserSearchForm();
            form.setAbmUserId(new UserId(Long.parseLong(primaryKey)));
            Page<UserDocument> documentList = userDocumentService.search(form);
            if (!documentList.isEmpty()) {
                for (UserDocument document : documentList) {
                    userDocumentService.deleteByIdCode(new UserIdCode(document.getIdCode()));
                }
            }
        }
    }

    public void saveUserBrandProvider(String primaryKey) {
        Long idCode = dealerBrandProviderRepository.getById(new DealerBrandProviderId(Long.parseLong(primaryKey)));
        if (idCode != null) {
            getInfoAndSaveDocument(Lists.newArrayList(idCode));
        }
    }

    public void sync() {
        UserSearchForm form = new UserSearchForm();
        form.setPageSize(500);
        int count = 0;
        while (true) {
            Map<String, List<UserDocument>> resultMap = userDocumentService.searchScroll(form);
            if (CollectionUtils.isEmpty(resultMap)) {
                log.info("resultMap empty, sync es count: {}", count);
                return;
            }
            List<UserDocument> scrollList = resultMap.values().stream()
                    .flatMap(Collection::stream)
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(scrollList)) {
                log.info("scrollList empty, sync es count: {}", count);
                return;
            }
            count = count + scrollList.size();
            log.info("sync es count: {}", count);
            getInfoAndSaveDocument(scrollList.stream()
                    .map(UserDocument::getIdCode)
                    .collect(Collectors.toList()));
            String nextScrollId = resultMap.keySet().stream()
                    .findFirst()
                    .orElse("");
            if (StringUtils.isBlank(nextScrollId)) {
                log.info("nextScrollId is blank, sync es count: {}", count);
                return;
            }
            form.setScrollId(nextScrollId);
        }
    }
}
